package com.quanyan.user.service.impl;

import com.google.common.base.Function;
import com.google.common.collect.ImmutableMultiset;
import com.google.common.collect.Lists;
import com.quanyan.api.APIResponse;
import com.quanyan.comment.response.LableBaseInfo;
import com.quanyan.comment.serviceFacade.CommentServiceFacade;
import com.quanyan.common.Plugin.PageObj;
import com.quanyan.common.constants.Constants;
import com.quanyan.common.utils.GsonUtils;
import com.quanyan.statium.api.resp.RespDatesportInfoDetail;
import com.quanyan.statium.service.DatesportDubboService;
import com.quanyan.user.mapper.DiscoveryVideoMapper;
import com.quanyan.user.mapper.TbVideoMapper;
import com.quanyan.user.mapper.TbVideoRelatedMapper;
import com.quanyan.user.model.db.*;
import com.quanyan.user.model.vo.DoyenActivity;
import com.quanyan.user.model.vo.VideoLabel;
import com.quanyan.user.model.vo.request.ReqNewsComment;
import com.quanyan.user.model.vo.request.ReqNewsPraise;
import com.quanyan.user.model.vo.response.*;
import com.quanyan.user.response.RespUserInfoBase;
import com.quanyan.user.response.RespVideoBaseInfo;
import com.quanyan.user.service.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by huadongyang on 2017/2/27.
 */
@Service
public class DiscoveryVideoServiceImpl implements DiscoveryVideoService {
    private static final Logger logger = LoggerFactory.getLogger(DiscoveryVideoServiceImpl.class);

    @Autowired
    private DiscoveryVideoMapper discoveryVideoMapper;

    @Autowired
    private UserQueryService userQueryService;

    @Autowired
    private UserFollowService userFollowService;

    @Autowired
    private NewsPraiseService newsPraiseService;

    @Autowired
    private NewsCommentService newsCommentService;

    @Value("${h5.video.share.url}")
    private String shareUrl;

    @Autowired
    private HttpClientService httpClientService;

    @Autowired
    private DatesportDubboService datesportDubboService;

    @Autowired
    private UserInfoService userInfoService;

    //视频推荐服务相关url
    private final String RECOMMENDED_URL = "tarento/video-details-part.html?videoId=";

    @Autowired
    private TbVideoMapper videoMapper;

    @Autowired
    private CommentServiceFacade commentServiceFacade;

    @Autowired
    private TbVideoRelatedMapper tbVideoRelatedMapper;

    @Override
    public APIResponse<RespVideoDetail> getDiscoveryVideoDetail(Integer uid, Integer videoId) {
        if (videoId == null || videoId <= 0 ) {
            return APIResponse.returnFail("请传必要参数");
        }
        RespVideoDetail respVideoDetail = null;
        try {
            respVideoDetail = discoveryVideoMapper.getDiscoveryVideoDetail(videoId);
            if (respVideoDetail != null ) {
                RespVideo respVideo = respVideoDetail.getRespVideo();
                if (respVideo != null) {
                    //设置视频发布者信息
                    TbUser tbUser = userQueryService.getUser(respVideo.getUid());
                    if (tbUser != null){
                        respVideoDetail.setUid(tbUser.getId());
                        respVideoDetail.setNickName(tbUser.getNickName());
                        respVideoDetail.setImageUrl(tbUser.getIcon());
                    }
                    //设置视频标签
                    List<Integer> lableIds = discoveryVideoMapper.getLableIds(videoId);

                    if (lableIds != null && lableIds.size()>0) {
                        List<LableBaseInfo> lableBaseInfos= commentServiceFacade.batchTagByIds(lableIds);
                        if (lableBaseInfos != null ) {
                            ImmutableMultiset<String> multisets = ImmutableMultiset.copyOf(Lists.transform(lableBaseInfos, new Function<LableBaseInfo, String>() {
                                        @Override
                                        public String apply(LableBaseInfo input) {
                                            return input.getText();
                                        }
                                    }
                            ));

                            respVideoDetail.getRespVideo().setLabelNames(multisets.asList());
                        }
                    }
                }

                //获取赞列表
                ReqNewsPraise reqNewsPraise = new ReqNewsPraise();
                reqNewsPraise.setPageNum(0);
                reqNewsPraise.setPageSize(2147483647);//显示6个赞
                reqNewsPraise.setDynamicDetailsId(respVideoDetail.getRespVideo().getNewsId());
                List<RespNewsPraise>  lstPraise  = newsPraiseService.getDynamicPraiseList(reqNewsPraise).getObject();
                if (lstPraise != null && lstPraise.size() > 0){
                    if (uid != null){
                        for (RespNewsPraise r : lstPraise ){
                            if (r.getUid().intValue() == uid ){
                                respVideoDetail.setIsPraise(1);
                                break;
                            }
                        }
                    }
                    if (lstPraise.size() > 5)
                        respVideoDetail.setPraises(lstPraise);
                    else
                        respVideoDetail.setPraises(lstPraise);
                }

                // 获取当前登录用户是否关注
                if (uid != null && respVideo != null){
                    TbUserFollow tbUserFollow = userFollowService.getTbUserFollow(uid, respVideo.getUid());
                    if (tbUserFollow != null )
                        respVideoDetail.setIsFollow(1);
                }

                //设置分享链接
                respVideoDetail.setShareUrl(shareUrl + videoId);

                //设置评论列表
                ReqNewsComment reqNewsComment = new ReqNewsComment();
                reqNewsComment.setPageNum(0);
                reqNewsComment.setPageSize(10);
                reqNewsComment.setDynamicDetailsId(respVideo.getNewsId());
                respVideoDetail.setDynamicComments(((PageObj<List<RespDynamicComment>>)newsCommentService.queryComment(reqNewsComment).getData()).getItems());

                //设置视频相关信息
                if(respVideo != null && respVideo.getModuleType().byteValue() == 1 ){
                    respVideoDetail.setRecommendedUrl(RECOMMENDED_URL + videoId);  //设置视频相关服务url
                    VideoRelatedInfo videoRelatedInfo = setDayenActivityInfos(videoId);
                    setDatesportInfos(videoId, videoRelatedInfo);
                    respVideoDetail.setVideoRelatedInfo(videoRelatedInfo);

                    respVideoDetail.setRecommendedVideos(discoveryVideoMapper.getRecommendedVideos(respVideo.getCategoryId(),respVideo.getId()));
                }

                //更新视频播放次数
                discoveryVideoMapper.updateVideoPV(videoId);

            }
        }catch (Exception e) {
            logger.error("获取视频详情失败：{}",e.getMessage());
            return APIResponse.returnFail("获取视频详情失败");
        }
        return APIResponse.returnSuccess(respVideoDetail);
    }

    private VideoRelatedInfo setDayenActivityInfos(Integer videoId) {
        List<Integer> activityIds = discoveryVideoMapper.getDarenVideoActivityIds(videoId);
        VideoRelatedInfo videoRelatedInfo = new VideoRelatedInfo();
        if (activityIds != null && activityIds.size() > 0) {
            DayenActivityInfo dayenActivityInfo = new DayenActivityInfo();
            List<DoyenActivity> doyenActivities = httpClientService.getDyActivity(activityIds);
            if (doyenActivities != null && doyenActivities.size() > 0) {
                dayenActivityInfo.setDarenActivitys(doyenActivities);
                dayenActivityInfo.setType((byte)1);
                //dayenActivityInfo.setSort();  Todo
                videoRelatedInfo.setDayenActivityInfo(dayenActivityInfo);
            }

        }
        return videoRelatedInfo;
    }

    private void setDatesportInfos(Integer videoId, VideoRelatedInfo videoRelatedInfo) {
        List<Integer> exerciseActivityIds = discoveryVideoMapper.getExerciseActivityIds(videoId);

        //设置约运动相关信息
        if (exerciseActivityIds != null && exerciseActivityIds.size() > 0) {
            List<RespDatesportInfoDetail> datesportInfoDetails = datesportDubboService.queryBatchDatesportDetails(exerciseActivityIds);
            if (datesportInfoDetails != null && datesportInfoDetails.size() > 0 ) {
                List<DatesportInfo> datesportInfos = new ArrayList<>();
                ExerciseActivityInfo exerciseActivityInfo = new ExerciseActivityInfo();
                DatesportInfo datesportInfo = new DatesportInfo();
                for (RespDatesportInfoDetail datesportInfoDetail : datesportInfoDetails) {
                    datesportInfo.setId(datesportInfoDetail.getId());
                    Integer createUid = datesportInfoDetail.getUid();
                    datesportInfo.setUid(createUid);
                    APIResponse apiResponse = userInfoService.queryUserInfo(createUid);
                    if (apiResponse != null && apiResponse.getData() != null) {
                        RespUserInfoBase userInfoBase = (RespUserInfoBase)apiResponse.getData();
                        datesportInfo.setNickName(userInfoBase.getNickName());
                        datesportInfo.setImageUrl(userInfoBase.getIcon());
                        datesportInfo.setGender(userInfoBase.getGender() != null ? userInfoBase.getGender().byteValue() : 0);
                    }

                    datesportInfo.setTitle(datesportInfoDetail.getTitle());
                    datesportInfo.setAddress(datesportInfoDetail.getAddress());
                    datesportInfo.setStartTime(datesportInfoDetail.getStartTime());
                    datesportInfo.setTotalNum(datesportInfoDetail.getPlayerCount());
                    datesportInfo.setParticipateNum(datesportInfoDetail.getJoinedCount());

                    datesportInfos.add(datesportInfo);
                }
                exerciseActivityInfo.setDatesportInfos(datesportInfos);
                exerciseActivityInfo.setType((byte)2);  //约运动
                //exerciseActivityInfo.setSort(); //TODO
                videoRelatedInfo.setExerciseActivityInfo(exerciseActivityInfo);
            }
        }
    }

    @Override
    public APIResponse<List<RespVideoDetail>> getVideoDetails(List<Integer> videoIds) {
        if (videoIds == null || videoIds.size()<= 0 ) {
            return APIResponse.returnFail("请传入正确的参数");
        }
        List<RespVideoDetail> videoDetails;
        try {
            videoDetails = discoveryVideoMapper.getVideoDetails(videoIds);
            if (videoDetails != null && videoDetails.size() > 0 ) {
                for (RespVideoDetail respVideoDetail : videoDetails) {
                    RespVideo respVideo = respVideoDetail.getRespVideo();
                    if (respVideo != null) {
                        //设置视频分享链接
                        respVideoDetail.setShareUrl(shareUrl + respVideo.getId());

                        //设置视频发布者信息
                        TbUser tbUser = userQueryService.getUser(respVideo.getUid());
                        if (tbUser != null){
                            respVideoDetail.setUid(tbUser.getId());
                            respVideoDetail.setNickName(tbUser.getNickName());
                            respVideoDetail.setImageUrl(tbUser.getIcon());
                        }

                        //设置视频标签
                        List<Integer> lableIds = discoveryVideoMapper.getLableIds(respVideo.getId());
                        //设置视频标签设置视频标签
                        if (lableIds != null && lableIds.size() > 0) {
                            List<LableBaseInfo> lableBaseInfos= commentServiceFacade.batchTagByIds(lableIds);
                            if (lableBaseInfos != null ) {
                                ImmutableMultiset<String> multisets = ImmutableMultiset.copyOf(Lists.transform(lableBaseInfos, new Function<LableBaseInfo, String>() {
                                            @Override
                                            public String apply(LableBaseInfo input) {
                                                return input.getText();
                                            }
                                        }
                                ));

                                respVideoDetail.getRespVideo().setLabelNames(multisets.asList());
                                respVideoDetail.getRespVideo().setLableBaseInfos(lableBaseInfos);
                            }
                        }
                    }
                }
            }
        }catch (Exception e) {
            logger.error("获取视频列表失败！：{}", e.getMessage());
            return APIResponse.returnFail("服务器异常");
        }
        return APIResponse.returnSuccess(videoDetails);
    }

    /**
     * 获取达人视频推荐列表
     * @param uidList
     * @return
     */
    @Override
    public Map<Integer, RespVideoBaseInfo> getTalentRecommendVideo(List<Integer> uidList) {
        Map<Integer, RespVideoBaseInfo> result = new HashMap<>();
        RespVideoBaseInfo video;
        for (Integer integer : uidList) {
            video = getTalentVideo(integer);
            if (video != null) {
                result.put(integer,video);
            }
        }
        logger.info("达人视频返回结果：{}", GsonUtils.toJson(result));
        return result;
    }

    /**
     * 获取达人最新视频
     * @param uid
     * @return
     */
    RespVideoBaseInfo getTalentVideo(int uid){
        TbVideoExample example = new TbVideoExample();
        example.setOrderByClause("create_time desc limit 0,1");
        TbVideoExample.Criteria criteria = example.createCriteria();
        criteria.andUidEqualTo(uid);
        criteria.andIsDeleteEqualTo(Constants.IS_DELETE_FALSE);
        List<TbVideo> videoList = videoMapper.selectByExample(example);
        if (videoList.isEmpty()) {
            return null;
        } else {
            RespVideoBaseInfo respVideo = new RespVideoBaseInfo();
            TbVideo video = videoList.get(0);
            respVideo.setId(video.getId());
            respVideo.setImageUrl(video.getImageUrl());
            respVideo.setDuration(video.getDuration());
            respVideo.setVideoUrl(video.getVideoUrl());
            respVideo.setTitle(video.getTitle());
            return respVideo;
        }
    }


    public List<VideoLabel>  videoLabel(List<Integer> videoIds){
        TbVideoRelatedExample example = new TbVideoRelatedExample();
        TbVideoRelatedExample.Criteria  criteria = example.createCriteria();
        criteria.andVideoIdIn(videoIds);
        criteria.andTypeEqualTo(1);
        List<TbVideoRelated> listRelated = tbVideoRelatedMapper.selectByExample(example);
        List<VideoLabel> videoLabelist = new ArrayList<>();

        if (listRelated != null && listRelated.size() > 0){
            List<Integer> labelIds = new ArrayList<>();
            for (TbVideoRelated t : listRelated){
                VideoLabel vidolabel = new VideoLabel();
                vidolabel.setVideoId(t.getVideoId());
                labelIds.add(t.getDataId());
                vidolabel.setTagId(t.getDataId());
                videoLabelist.add(vidolabel);
            }
            try {
                List<LableBaseInfo> result = commentServiceFacade.batchTagByIds(labelIds);

                for (LableBaseInfo l : result ){
                    for (VideoLabel v : videoLabelist){
                        if (v.getTagId().intValue() == l.getId().intValue() ){
                            v.setLabelName(l.getText());
                        }
                    }
                }

            } catch (Exception e) {
                logger.error("查询标签异常;{}",e);
                videoLabelist = new ArrayList<>();
            }
        }
       return videoLabelist;
    }

    public  ImmutableMultiset<Integer> getDataId( List<TbVideoRelated> listRelated) {
        return ImmutableMultiset.copyOf(Lists.transform(listRelated, new Function<TbVideoRelated, Integer>() {
                    @Override
                    public Integer apply(TbVideoRelated input) {
                        return input.getDataId();
                    }
                }
        ));
    }

}
